var require = globalThis._require;
var nhttp = require("@native.http");
var error = require("error.js");

var __FILE__ = "http.js";
var ERR = new error.ThrowError(__FILE__);

function format_headers(headers) {
        // 将headers转换为字符串
        var headerStr = "";

        var keys = Object.keys(headers);
        var key = null,
            value = null;
        for (var i = 0; i < keys.length; i++) {
            key = keys[i];
            value = headers[key];
            headerStr += key + ":" + value + "\r\n";
        }
        headerStr += "\r\n";

        return headerStr;
}

function asset_options(options) {
    if (typeof options.url != "string") return "options url invaild";
    if (options.method != "GET" && options.method != "POST") return "options method invaild";
    if (typeof options.timeout != "number") return "options timeout invaild";
    if (options.responseType != "text" && options.responseType != "blob") options.responseType = "text";
    if (options.data != undefined && options.data != null && typeof options.data != "string") return "options data invaild";
    if (options.headers != undefined && options.headers != null && typeof options.headers != "object") return "options headers invaild";
    return null;
}

function Request(options) {
    this.__id__ = -1;
    this.options = options;

    this.init = function () {
        var res = asset_options(this.options)
        if (res != null) {
            ERR.trace("Request", 44, "HTTP_OPTION_ERROR", res);
        }
        
        // 注册响应回调函数
        this.__id__ = globalThis.eventbus.on(this, "recv", this.responseCallback);

        // 将对象序列化为字符串
        var url = this.options.url;
        var data = this.options.data;
        var method = this.options.method;
        var timeout = this.options.timeout;
        var responseType = this.options.responseType;
        var headerStr = format_headers(this.options.headers);

        // 发送http请求
        nhttp.request(
            method,
            url,
            headerStr,
            data,
            responseType,
            timeout,
            this.__id__
        );
    }

    this.responseCallback = function(buffer, statusCode, headers) {
        var options = this.options;

        var failCallback = options.fail;
        var successCallback = options.success;
        var completeCallback = options.complete;
        var validateStatusCallback = options.validateStatus;
    
        if (options.responseType == "json") {
            buffer = JSON.stringify(buffer);
        }

        // 返回参数封装
        var result = {
            data: buffer,
            statusCode: statusCode,
            headers: headers,
            config: {
                url: options.url,
                data: options.data,
                method: options.method,
                headers: options.headers,
                timeout: options.timeout,
            },
        };
    
        // 判断成功还是失败
        var success = false;
        if (typeof validateStatusCallback == "function") {
            success = validateStatusCallback(statusCode);
            if (typeof success != "boolean") {
                throw new Error("validate status function must be return a boolean type");
            }
        } else if (statusCode >= 200 && statusCode < 300) {
            success = true;
        }
    
        // 根据成功或者失败标志，调用对应回调函数
        if (success == true && typeof successCallback == "function") {
            successCallback(result);
        } else if (typeof failCallback == "function") {
            failCallback(result);
        }
        if (typeof completeCallback == "function") {
            completeCallback(result);
        }
    
        // 回调执行完毕，删除注册实例
        globalThis.eventbus.detach(this);
    };
}

function request(options) {
    var req = new Request(options);
    req.init()
    return req;
}

if (globalThis.platform == "nodejs") {
    module.exports = {
        request: request,
    };
}
